package cn.openea.perpartner.meily.web.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import cn.openea.perpartner.common.core.exception.ServiceException;
import cn.openea.perpartner.common.core.utils.Arith;
import cn.openea.perpartner.common.core.utils.StringUtils;
import cn.openea.perpartner.common.core.web.domain.AjaxResult;
import cn.openea.perpartner.meily.constant.enums.EnterpriseRelevancyItemEnums;
import cn.openea.perpartner.meily.web.entity.Article;
import cn.openea.perpartner.meily.web.entity.Enterprise;
import cn.openea.perpartner.meily.web.entity.Goods;
import cn.openea.perpartner.meily.web.entity.vo.EnterpriseRelevancyItemVo;
import cn.openea.perpartner.meily.web.entity.vo.EnterpriseSearchVo;
import cn.openea.perpartner.meily.web.mapper.EnterpriseMapper;
import cn.openea.perpartner.meily.web.service.IEnterpriseService;
import cn.openea.perpartner.meily.web.service.IGoodsService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

/**
 * (Enterprise)表服务实现类
 *
 * @author Weird077
 * @since 2023-05-28 10:23:40
 */
@Slf4j
@Service("enterpriseService")
public class EnterpriseServiceImpl extends ServiceImpl<EnterpriseMapper, Enterprise> implements IEnterpriseService {

    @Value("${sso.url}")
    private String sso_url;
    @Value("${common.uri}")
    private String common_uri;
    @Value("${meily.header.sysid}")
    private String sysId;
    @Value("${meily.header.syspwd}")
    private String sysPwd;
    @Resource
    private IGoodsService goodsService;

    @Override
    public List<Enterprise> selectList(EnterpriseSearchVo searchVo) {
        return list(buildQueryWrapper(searchVo, true));
    }

    @Override
    public Enterprise getByEnterpriseNo(String enterpriseNo) {
        if (StringUtils.isBlank(enterpriseNo)) {
            return null;
        }
        return baseMapper.selectOne(new LambdaQueryWrapper<Enterprise>().eq(Enterprise::getEnterpriseNo, enterpriseNo));
    }

    private LambdaQueryWrapper<Enterprise> buildQueryWrapper(EnterpriseSearchVo searchVo, boolean isSort) {
        if (null == searchVo) {
            return null;
        }
        searchVo.buildDateRangeParams();
        LambdaQueryWrapper<Enterprise> queryWrapper = new LambdaQueryWrapper<>();
        Short isTop = searchVo.getIsTop();
        if (isTop != null) {
            queryWrapper = isTop == (short) 0 ? queryWrapper.eq(Enterprise::getEnterpriseTop, 0)
                    : queryWrapper.gt(Enterprise::getEnterpriseTop, 0);
        }
        if (StrUtil.isNotBlank(searchVo.getEnterpriseName())) {
            queryWrapper.like(Enterprise::getEnterpriseName, searchVo.getEnterpriseName());
        }
        if (StrUtil.isNotBlank(searchVo.getEnterpriseNo())) {
            queryWrapper.like(Enterprise::getEnterpriseNo, searchVo.getEnterpriseNo());
        }
        if (StringUtils.isNotBlank(searchVo.getSearchStr())) {
            queryWrapper.and(query -> query.like(Enterprise::getEnterpriseNo, searchVo.getSearchStr())
                    .or().like(Enterprise::getEnterpriseName, searchVo.getSearchStr())
                    .or().like(Enterprise::getBusinessScope, searchVo.getSearchStr())
                    .or().like(Enterprise::getIndustry, searchVo.getSearchStr())
                    .or().like(Enterprise::getProvince, searchVo.getSearchStr())
                    .or().like(Enterprise::getCity, searchVo.getSearchStr()));
        }
        if (StringUtils.isNotBlank(searchVo.getStartDate()) && StringUtils.isNotBlank(searchVo.getEndDate())) {
            queryWrapper.apply("DATE(create_time) BETWEEN '" + searchVo.getStartDate() + "' AND '" + searchVo.getEndDate() + "'");
        }
        if (StringUtils.isNotBlank(searchVo.getUpdateDateRange()) && JSONUtil.isJson(searchVo.getUpdateDateRange())){
            JSONObject jsonObject = JSON.parseObject(searchVo.getUpdateDateRange());
            String startDate = jsonObject.getString("startDate");
            String endDate = jsonObject.getString("endDate");
            if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)){
                queryWrapper.apply("DATE(update_time) BETWEEN '" + startDate + "' AND '" + endDate + "'");
            }
        }
        if (isSort) {
            queryWrapper.orderByDesc(Enterprise::getEnterpriseTop);
            queryWrapper.orderByDesc(Enterprise::getUpdateTime);
        }
        return queryWrapper;
    }


    @Override
    public List<Enterprise> selectAll() {
        return baseMapper.selectList(new LambdaQueryWrapper<Enterprise>().orderByDesc(Enterprise::getCreateTime));
    }

    @Override
    public boolean deleteEnterprise(List<String> idList) {
        String url = sso_url.concat("/applets/delete");
        JSONObject result = doPost(url, idList.toString());
        if (result.getString(AjaxResult.CODE_TAG).equals(Convert.toStr(AjaxResult.Type.SUCCESS.value()))) {
            return removeBatchByIds(idList);
        }
        return false;
    }

    @Override
    public void addEnterprise(Enterprise enterprise) {
        // 判断参数
        String msg = enterprise.checkParams();
        if (StringUtils.isNotBlank(msg)) {
            throw new ServiceException("企业编号不能为空");
        }
        // 判断是否存在 通过统一信用代码和名称判断
        if (dataExists(enterprise.getEnterpriseName(), enterprise.getOrganizationCode())) {
            throw new ServiceException(enterprise.getEnterpriseName() + "已录入");
        }
        JSONObject params = new JSONObject();
        params.put("nickname", enterprise.getEnterpriseName());
        params.put("phonenumber", enterprise.getPhoneNumber());
        String url = sso_url.concat("/applets/create");
        JSONObject result = doPost(url, params.toJSONString());
        if (!Convert.toStr(AjaxResult.Type.SUCCESS.value()).equals(result.getString(AjaxResult.CODE_TAG))) {
            throw new ServiceException("创建平台身份失败，失败原因" + result.getString(AjaxResult.MSG_TAG));
        }
        String userId = result.getString("userId");
        enterprise.setUserId(Convert.toLong(userId));
        enterprise.setNickName(enterprise.getEnterpriseName());
        save(enterprise);
    }

    @Override
    public void edit(Enterprise enterprise) {
        String msg = enterprise.checkParams();
        if (StringUtils.isNotBlank(msg)) {
            throw new ServiceException("企业编号不能为空");
        }
        Optional.ofNullable(getById(enterprise.getUserId()))
                .orElseThrow(() -> new ServiceException("企业不存在"));
        Enterprise repeatResult = baseMapper.findByNameOrOrganizationCode(enterprise.getEnterpriseName(),
                enterprise.getOrganizationCode());
        if (!repeatResult.getUserId().equals(enterprise.getUserId())) {
            throw new ServiceException(enterprise.getEnterpriseName() + "已存在");
        }
        updateById(enterprise);
    }

    @Override
    public String createQrCode(long userId) {
        Enterprise enterprise = getById(userId);
        String cosUrl = enterprise.getTransferCode();
        if (StrUtil.isNotBlank(cosUrl)) {
            return cosUrl;
        }
        JSONObject params = new JSONObject();
        params.put("userId", userId);
        params.put("shareType", "EP");
        String url = common_uri.concat("/share/qrcode");
        JSONObject result = doPost(url, params.toJSONString());
        if (result.getString(AjaxResult.CODE_TAG).equals(Convert.toStr(AjaxResult.Type.SUCCESS.value()))) {
            cosUrl = result.getString("data");
            enterprise.setTransferCode(cosUrl);
            updateById(enterprise);
        }
        return cosUrl;
    }

    /**
     * 推荐（置顶）
     *
     * @param userId
     * @return
     */
    @Override
    public boolean top(Long userId) {
        Optional.ofNullable(baseMapper.selectById(userId))
                .orElseThrow(() -> new ServiceException("企业不存在！"));
        Enterprise enterprise = getOne(Wrappers.<Enterprise>lambdaQuery()
                .orderByDesc(Enterprise::getEnterpriseTop)
                .last("limit 1"));
        // 初始值为1
        int enterpriseTop = 1;
        if (BeanUtil.isNotEmpty(enterprise)) {
            enterpriseTop = Convert.toInt(Arith.add(enterprise.getEnterpriseTop(), 1));
        }
        return updateById(Enterprise.builder()
                .userId(userId)
                .enterpriseTop(enterpriseTop)
                .build());
    }

    /**
     * 取消推荐（取消置顶）
     *
     * @param userId
     * @return
     */
    @Override
    public boolean topCancel(Long userId) {
        Enterprise oldEnterprise = Optional.ofNullable(baseMapper.selectById(userId))
                .orElseThrow(() -> new ServiceException("企业不存在！"));
        if (oldEnterprise.getEnterpriseTop() == 0) {
            return true;
        }
        Enterprise enterprise = getOne(Wrappers.<Enterprise>lambdaQuery()
                .orderByDesc(Enterprise::getEnterpriseTop)
                .last("limit 1"));
        if (!enterprise.getUserId().equals(userId)) {
            // 对企业进行降级
            baseMapper.downgradeTop(oldEnterprise.getEnterpriseTop());
        }
        return updateById(Enterprise.builder()
                .userId(userId)
                .enterpriseTop(0).build());
    }

    /**
     * 获取推荐企业列表（置顶企业）
     */
    @Override
    public List<Enterprise> getTopList() {
        LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
        wrapper.gt(Enterprise::getEnterpriseTop, 0);
        wrapper.orderByDesc(Enterprise::getEnterpriseTop);
        return list(wrapper);
    }

    /**
     * 随机企业用户资源
     * @param vo
     * @return
     */
    @Override
    public List<Enterprise> getRandomList(EnterpriseSearchVo vo) {

        if(vo.getRandomQuantity() == 0){
            vo.setRandomQuantity(5);
        }
        LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
        wrapper.last(" ORDER BY RAND() LIMIT " + vo.getRandomQuantity());
        return list(wrapper);
    }

    /**
     * 获取相似企业
     * 关联字段是“所属行业”，最多展示5条数据即可
     * @param vo
     * @return
     */
    @Override
    public List<Enterprise> getSimilarList(EnterpriseSearchVo vo) {
        if(vo.getRandomQuantity() == 0){
            vo.setRandomQuantity(5);
        }
        LambdaQueryWrapper<Enterprise> wrapper = new LambdaQueryWrapper<>();
        if(StrUtil.isNotBlank(vo.getIndustry())){
            wrapper.eq(Enterprise::getIndustry, vo.getIndustry());
        }
        // 排除当前企业
        if(StrUtil.isNotBlank(vo.getEnterpriseNo())){
            wrapper.ne(Enterprise::getEnterpriseNo, vo.getEnterpriseNo());
        }
        wrapper.last(" ORDER BY RAND() LIMIT " + vo.getRandomQuantity());
        return list(wrapper);
    }

    /**
     * 获取企业关联品牌
     * @param vo
     * @return
     */
    @Override
    public List<Goods> getAssociateBrandList(EnterpriseSearchVo vo) {
        LambdaQueryWrapper<Goods> wrapper = new LambdaQueryWrapper<>();
        // 企业编号
        if(StrUtil.isNotBlank(vo.getEnterpriseNo())){
            wrapper.eq(Goods::getEnterpriseNo, vo.getEnterpriseNo());
        }
        wrapper.orderByDesc(Goods::getBrand);
        return goodsService.list(wrapper);
    }

    @Override
    public boolean dataExists(String enterpriseName, String organizationCode) {
        return baseMapper.existenceByNameOrOrganizationCode(enterpriseName, organizationCode) != null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void relevancyItems(@NonNull EnterpriseRelevancyItemVo relevancyItemVo) {
        Enterprise enterprise = Optional.ofNullable(getByEnterpriseNo(relevancyItemVo.getEnterpriseNo()))
                .orElseThrow(() -> new ServiceException("企业不存在"));
        EnterpriseRelevancyItemEnums relevancyItem = relevancyItemVo.getRelevancyItem();
        if (null == relevancyItem) {
            throw new ServiceException("数据异常");
        }
        List<String> itemIds = relevancyItemVo.getItemIds();
        itemIds.forEach(id -> {
            relevancyItem.addRelevancy(id, enterprise);
        });
    }

    private JSONObject doPost(String url, String params) {
        HttpResponse response = HttpRequest.post(url)
                .header("Content-Type", "application/json")
                .header("Accept", "application/json")
                .header("sysid", sysId)
                .header("syspwd", sysPwd)
                .body(params)
                .execute();
        return JSON.parseObject(response.body());
    }
}

